--[[

    Filename:	auxdbg.lua

    Programmer:	aesiot

    Remark:

--]]

local auxdbg = { _VERSION = "1.0" }

--------------------------------------------------------------------------------

function auxdbg.debug()

	local src = {

		print = print
	}

	print = function( name, level )

		auxdbg.print_local( name, level or 5 )
	end

	debug.debug()

	print = src.print
end

--------------------------------------------------------------------------------

local function is_array( v )

	if "table" ~= type( v ) then

		return false
	end

	local c = 0

	for k, x in pairs( v ) do

		c = c + 1
	end

	return c == #v
end

local function json_filter( t, loop )

	local c = type( t )

	if "table" == c then

		loop = ( ( "table" == type( loop ) and loop ) or {} )

		for i, v in ipairs( loop ) do

			if v == t then

				return tostring( t )
			end
		end

		local r = {}

		table.insert( loop, t )

		if is_array( t ) then

			for i, v in ipairs( t ) do

				r[ i ] = json_filter( v, loop )
			end
		else

			for k, v in pairs( t ) do

				r[ tostring( k ) ] = json_filter( v, loop )
			end
		end

		table.remove( loop )

		return r

	elseif "thread" == c then

		return tostring( t )

	elseif "function" == c then

		return tostring( t )

	elseif "userdata" == c then

		return ( null == t and t ) or tostring( t )

	elseif "number" == c then

		return ( t == math.huge and "1.#INF" ) or t
	else

		return t
	end
end

local function to_json( data, mode )

	return require( "JSON" ).encode( json_filter( data ), mode )
end

function auxdbg.print( v )

	if "table" ~= type( v ) then

		logger.d( v )
	else

		logger.d( to_json( v, true ) )
	end
end

--------------------------------------------------------------------------------

function auxdbg.print_local( variable_name, stack_index )

	if nil == stack_index then

		stack_index = 3
	end

	if "nil" == type( variable_name ) then

		local count = 0

		local strlen = 0

		while true do

			local name, data = debug.getlocal( stack_index + 1, count + 1 )

			if not name then

				break
			end

			count = count + 1

			strlen = math.max( strlen, #name )
		end

		for index = 1, count do

			local name, data = debug.getlocal( stack_index + 1, index )

			local str = string.format( "%-5d %s", index, name )

			local n = strlen // 8 + 1

			if 0 ~= strlen % 8 then

				n = n + 1
			end

			n = n - #str // 8

			for i = 1, n do

				str = str .. '\t'
			end

			str = str .. type( data ) .. '\t'

			if 0 ~= #( type( data ) ) % 8 then

				str = str .. '\t'
			end

			str = str .. tostring( data )

			logger.d( str )
		end

	elseif "string" == type( variable_name ) then

		local count = 0

		while true do

			local name, data = debug.getlocal( stack_index + 1, count + 1 )

			if not name then

				break
			end

			count = count + 1

			if variable_name == name then

				auxdbg.print( data )

				return
			end
		end

		auxdbg.print( _G[ variable_name ] )

	elseif "number" == type( variable_name ) and "integer" == math.type( variable_name ) then

		local count = 0

		while true do

			local name, data = debug.getlocal( stack_index + 1, count + 1 )

			if not name then

				break
			end

			count = count + 1

			if variable_name == count then

				auxdbg.print( data )

				break
			end
		end
	end
end

--------------------------------------------------------------------------------

return auxdbg
